/**
 * @file    app_user.c
 * @author  Azolla (1228449928@qq.com)
 * @brief
 * @version 0.1
 * @date    2022-09-19
 * 
 * @copyright Copyright (c) 2022
 * */
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/event_groups.h"
#include "nvs_flash.h"
#include "esp_log.h"
#include "esp_system.h"
#include "mbedtls/base64.h"
 
#include "wifi_init.h"
#include "wifi_sock.h"
#include "wifi_sntp.h"
#include "wifi_user.h"
#include "wifi_ota.h"
#include "wifi_mqtt.h"

#include "app_user.h"
 
 
#define TAG  "app_user"

/* 百度账号
 * 13860115663
 * yirui1234
 * */

#ifdef TAG
#define LOGI(format, ...)    ESP_LOGI(TAG, format, ##__VA_ARGS__)
#define LOGW(format, ...)    ESP_LOGW(TAG, format, ##__VA_ARGS__)
#define LOGE(format, ...)    ESP_LOGE(TAG, format, ##__VA_ARGS__)
#else
#define LOGI(format, ...)
#define LOGW(format, ...)
#define LOGE(format, ...)
#endif

//==============================================================================================================
//==============================================================================================================
 
typedef struct {

    bool sys_reset;        // 1: 软件复位
    bool adc_onoff;
} app_run_t;
static app_run_t app = { 0 };

typedef struct {
 
    uint8_t update;  // 1: 有更新
} nvs_user_t;
static nvs_user_t nvs_user;
 
esp_err_t nvs_user_handle(nvs_user_t *nvs, nvs_open_mode_t nvs_open_mode)
{
    return nvs_blob_handle((nvs_user_t *)nvs, sizeof(nvs_user_t), "user_key", nvs_open_mode);
}
 
//==============================================================================================================
//==============================================================================================================
 
 
//==============================================================================================================
//==============================================================================================================
#define KEY_RESET_FACTORY   0       // IO0
#define KEY_CLEAR_NETWORK   3       // IO3
static void key_scan_task(void)
{
    return;
    static uint8_t key_time = 0;
    static uint8_t key_value = 0;
    union8_t key_temp = { .value = 0 };
    key_temp.bits.bit0 = !gpio_get_level(KEY_RESET_FACTORY);
    // key_temp.bits.bit1 = !gpio_get_level(KEY_CLEAR_NETWORK);
    // LOGI("KEY->key_temp = 0x%02x", key_temp.value);
    if (key_value && key_value == key_temp.value) { // 键值保持不变！
        if (++key_time == 80) {  // 5s
            if (key_temp.bits.bit0 == true) {  // IO0
                //esp_ota_reset_factory();  // 恢复到出厂固件
            } else if (key_temp.bits.bit1 == true) {   // IO21

            }
            LOGI("KEY->app.sys_reset = %d\r\n", key_value);
            app.sys_reset = true;  // 使能软复位
            app.adc_onoff = !app.adc_onoff;
        }
    } else { // 键值发现了变化！
        if ((key_value && !key_temp.value) && (key_time > 1 && key_time < 10)) {  // 单击
            printf("\r\n");
            LOGI("KEY->Click = 0x%02x", key_value);
            app.adc_onoff = !app.adc_onoff;
            // if (app.adc_onoff) adc_read_start();
            // else adc_read_stop();
        }
        key_value = key_temp.value;
        key_time = 0;
    }
    return;
}

//=====================================================================================
//=====================================================================================
bool get_sys_config_network(void)  // LVGL显示用
{
    return false;  // 是否配网成功了
}

void esp_free_heap_print(void)
{
    #if 1  // debug
    LOGI("Free heap, current: %ld, minimum: %ld", 
                esp_get_free_heap_size(), 
                esp_get_minimum_free_heap_size());  // 打印内存
    LOGI("MALLOC_CAP_SPIRAM = %d, MALLOC_CAP_INTERNAL = %d", 
                heap_caps_get_free_size(MALLOC_CAP_SPIRAM), 
                heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
    #endif
}

void app_user_handle(void)
{
    key_scan_task();
 
    /* 用户信息有更新 */
    if (nvs_user.update) {
        nvs_user.update = false;
        nvs_user_handle(&nvs_user, NVS_READWRITE);   // 写用户信息
    }
}


//=============================================================================================================== 
//=============================================================================================================== 
// 用户逻辑功能任务
static void app_user_task(void *arg)
{ 
    while (520) {
        //=============================================================================
        // START... 
        //=============================================================================
        vTaskDelay(100);  /* 主任务执行的周期/MS */

        //=============================================================================
        app_user_handle();

        //=============================================================================
        #if 1
        static uint8_t freetime = 200;
        if (++freetime > 200) {
            freetime = 0;
            esp_free_heap_print();  
        }
        #endif

        //============================================================================
        // END...
    }
}
 
//=============================================================================================================== 
//=============================================================================================================== 
void uart_recv_callback(uart_port_t port, uint8_t *data, uint16_t len)
{
    LOGI("uart = %s | %d", data, len);
    //esp_log_buffer_hex("uart", data, len);
    
}

 
//===================================================================================================================
//===================================================================================================================
void app_user_init(void) 
{
    LOGW("app_user_init...");
    nvs_user_handle(&nvs_user, NVS_READONLY);   // 读用户信息
 

    vTaskDelay(100);

    //hal_uart_init(uart_recv_callback);
 
    xTaskCreatePinnedToCore(app_user_task, "app_user", 8 * 1024, NULL, 5, NULL, APP_CPU_NUM);

    /* END...................................................................................*/
}
/* END...................................................................................*/
// 查看错误码信息： https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/error-codes.html
// http://wiki.tjc1688.com/doku.php 
